<?php

namespace app\api\service\alipay;

use app\api\controller\Base;
use think\Loader;

Loader::import('Alipay_APP.aop.AopClient');
Loader::import('Alipay_APP.aop.request.AlipayTradeAppPayRequest');
Loader::import('Alipay_APP.aop.request.AlipayTradeRefundRequest');

/**
 * 支付宝支付类
 */
class BasePay extends Base
{

    private $aop;
    // 支付宝网关
    const gatewayUrl = "https://openapi.alipay.com/gateway.do";
    // 异步通知地址,只有扫码支付预下单可用
    const notify_url = "";

    public function __construct()
    {
        $aop = new \AopClient();
        $aop->gatewayUrl = self::gatewayUrl;
        $aop->appId = config('alipay.app_id'); // 应用ID
        $aop->rsaPrivateKey = config('alipay.merchant_private_key'); // 商户私钥
        $aop->alipayrsaPublicKey = config('alipay.alipay_public_key'); // 支付宝公钥
        $aop->format = "json";
        $aop->charset = "UTF-8";
        $aop->signType = "RSA2";
        $this->aop = $aop;
    }

    /**
     * 支付入口方法
     *
     * @param $body 订单详情
     * @param $subject 订单标题
     * @param $orderNO 订单号
     * @param $total_amount 订单金额
     * @param $notify_url 异步通知地址
     * @return string
     */
    public function run($body, $subject, $orderNO, $total_amount, $notify_url)
    {
        return $this->pay($body, $subject, $orderNO, $total_amount, $notify_url);
    }

    /**
     * 支付
     */
    private function pay($body, $subject, $orderNO, $total_amount, $notify_url)
    {

        // 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        $request = new \AlipayTradeAppPayRequest();

        // 异步通知地址
        $notify_url = $notify_url;
        //$notify_url = urlencode($notify_url); // 商户外网可以访问的异步地址
        // 订单标题
        $subject = $subject;
        // 订单详情
        $body = $body;
        // 订单号，示例代码使用时间值作为唯一的订单ID号
        $out_trade_no = $orderNO;
        // 订单总金额，单位为元，精确到小数点后两位
        $total_amount = $total_amount / 100;

        //SDK已经封装掉了公共参数，这里只需要传入业务参数
        $bizcontent = "{\"body\":\"".$body."\","
            . "\"subject\": \"".$subject."\","
            . "\"out_trade_no\": \"".$out_trade_no."\","
            . "\"timeout_express\": \"30m\","
            . "\"total_amount\": \"".$total_amount."\","
            . "\"product_code\":\"QUICK_MSECURITY_PAY\""
            . "}";
        $request->setNotifyUrl($notify_url);
        $request->setBizContent($bizcontent);
        //这里和普通的接口调用不同，使用的是sdkExecute
        $response = $this->aop->sdkExecute($request);

        // 注意：这里不需要使用htmlspecialchars进行转义，直接返回即可
        //echo $response;
        return $response;
    }

    /**
     * 退款
     */
    public function refund($body,$subject,$refund_no,$total_amount){

        $total_amount = sprintf("%.2f",$total_amount/100);
        $request = new \AlipayTradeRefundRequest ();
        $bizcontent = "{\"body\":\"".$body."\","
            . "\"subject\": \"".$subject."\","
            . "\"trade_no\": \"".$refund_no."\","
            . "\"timeout_express\": \"30m\","
            . "\"total_amount\": \"".$total_amount."\","
            . "\"product_code\":\"QUICK_MSECURITY_PAY\""
            . "}";
        $request->setBizContent($bizcontent);
        $result = $this->aop->execute($request);
        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $result->$responseNode->code;
        $resultMsg = $result->$responseNode->msg;
        $data = [];
        if($resultCode == '10000' && $resultMsg == 'Success'){
            $data['code'] = $resultCode;
            $data['msg'] = $resultMsg;
            $data['trade_no'] = $result->$responseNode->trade_no;
            $data['gmt_refund_pay'] = $result->$responseNode->gmt_refund_pay;
        }else{
            $data['code'] = '0';
            $data['msg'] = '退款失败';
        }
        return $data;
    }
}